using System;
using System.Collections.Generic;
using System.Text;
using Evolution.Engine.Interfaces;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Evolution.Engine.Objects;

namespace Evolution.Engine.Managers
{
    public class EnvironmentManager : Singleton<EnvironmentManager>, Evolution.Engine.Interfaces.IUpdateable
    {
        private float _TimeCompressionFactor = 0.1f;
        private List<Light> _SkyObjects = new List<Light>();
        private float _UpdateFactor = 0;
        private float _AmbientColor;
        private float _BlockSize = 30;
        private float _BlockHeight = 30;

        public float BlockHeight { get { return _BlockHeight; } set { _BlockHeight = value; } }
        public float BlockSize { get { return _BlockSize; } set { _BlockSize = value; } }
        public float WaterHeight = 9.3f;

        public float AmbientColor { get { return _AmbientColor; } set { _AmbientColor = value; } }
        public List<Light> SkyObjects { get { return _SkyObjects; } set { _SkyObjects = value; } }
        public float TimeCompressionFactor { get { return _TimeCompressionFactor; } set { _TimeCompressionFactor = value; } }

        private float _Friction = 0.65f;
        private float _AirFriction = 0.1f;
        private Vector3 _Gravity = new Vector3(0, -0.0001f, 0);
        private float _Traction = 1.0f;

        public float Traction { get { return _Traction; } set { _Traction = value; } }
        public Vector3 Gravity { get { return _Gravity; } set { _Gravity = value; } }
        public float AirFriction { get { return _AirFriction; } set { _AirFriction = value; } }
        public float Friction { get { return _Friction; } set { _Friction = value; } }

        public EnvironmentManager()
        {
            FogManager.Instance.Enabled = true;
            FogManager.Instance.SetFog();
        }

        #region IUpdateable Members

        public void Update(GameTime gameTime)
        {
            foreach (Light obj in _SkyObjects)
            {
                _UpdateFactor = (float)gameTime.TotalRealTime.TotalSeconds / obj.HoursInDay * _TimeCompressionFactor;
                UpdateSkyObject(gameTime, obj);
            }
        }
        private void UpdateSkyObject(GameTime gameTime, Light obj)
        {
            Vector3 pos = obj.Position;

            pos.X = (float)Math.Cos(_UpdateFactor);
            pos.Y = (float)Math.Cos(_UpdateFactor);

            // Sun elevation in the sky, -.5f makes the days slightly longer than nights
            pos.Z = (float)((.5f * Math.Sin(_UpdateFactor)) - .3f);

            // Clamp the AmbientPower so it never goes completely black
            obj.Ambient = new Vector4(MathHelper.Clamp(-pos.Z, 0.5f, 0.8f));

            obj.Position = pos;
            obj.Position.Normalize();
        }

        #endregion
    }
}
